package com.jredu.other;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;

import com.jredu.util.SpringContextUtil;
import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException;

public class QuartzJobFactory {
	
	
	private static Scheduler scheduler = getScheduler();

	
	
	/**
     * 创建一个定时任务
     * 
     * @param scheduler
     * @param job
	 * @return 
     * @throws SchedulerException
     * @throws Exception
     */
    public static void createSheduler(QuartzScheduleJob job) throws Exception {
    	// 在工作状态可用时,即job_status = 1 ,开始创建
    	if(job.getJobStatus().equals("1")){
    		// 新建一个基于Spring的管理Job类
    		MethodInvokingJobDetailFactoryBean methodInvJobDetailFB = new MethodInvokingJobDetailFactoryBean();
    		// 设置Job名称
    		methodInvJobDetailFB.setName(job.getJobName());
    		// 是Spring中定义的Bean
    		if(job.getIsSpringBean().equals("1")){
    			methodInvJobDetailFB.setTargetObject(SpringContextUtil.getBean(job.getTargetObject()));
    		}else {
    			methodInvJobDetailFB.setTargetObject(Class.forName(job.getClazz()).newInstance());
    		}
    		
    		// 设置任务方法
            methodInvJobDetailFB.setTargetMethod(job.getTargetMethod());
         // 将管理Job类提交到计划管理类
            methodInvJobDetailFB.afterPropertiesSet();
            /** 并发设置 */
            methodInvJobDetailFB.setConcurrent(job.getConcurrent().equals("1") ? true : false);
            JobDetail jobDetail = methodInvJobDetailFB.getObject();// 动态
            jobDetail.getJobDataMap().put("scheduleJob", job);
//        	方式2
            CronScheduleBuilder scheduleBuilder = 
            		CronScheduleBuilder.cronSchedule(job.getCronExpression());
            // 按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = 
            		TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
                    .withSchedule(scheduleBuilder).build();
            //如果任务调度器未启动
            if(!scheduler.isStarted()){  
            	start();  
                scheduler.scheduleJob(jobDetail, trigger);// 将相关的Job注入到管理类
            }

    	}
    	
    }
    
    /**
     * 修改CronExpression
     * @param job
     */
    public static void modifyJobCronExpression(QuartzScheduleJob job){
    	//构建trigger的两种方式  方式1
        String triggerName;
		try {
			if (!isShutdown()) {
				triggerName = scheduler.getTriggersOfJob(new JobKey(job.getJobName(), 
						job.getJobGroup())).get(0).getKey().getName();
				CronTriggerImpl triggerCron;
				triggerCron = (CronTriggerImpl)scheduler.getTrigger(new TriggerKey(triggerName));
				triggerCron.setCronExpression(job.getCronExpression());
				scheduler.rescheduleJob(new TriggerKey(job.getJobName(), 
						job.getJobGroup()), triggerCron);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (SchedulerException e) {
			e.printStackTrace();
		} catch (java.text.ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }

    /**
     * 启动一个调度对象
     * @throws SchedulerException
     */
    public static void start() throws SchedulerException {
    	if (!scheduler.isShutdown()) {
        	scheduler.start();
		}
    } 
    
    /**
     * 判断调度器是否关闭
     * @return
     */
    private static boolean isShutdown(){
    	try {
			return scheduler.isShutdown();
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
    	return false;
    }
    
    /**
     * 调度是否启动
     * @return
     * @throws SchedulerException
     */
    public static boolean isStarted() throws SchedulerException { 
    	return scheduler.isStarted(); 
    } 
    
    /**
     * 关闭调度器
     * @throws SchedulerException
     */
    public static void shutdown() throws SchedulerException { 
    	scheduler.shutdown(); 
    } 
    
    /**
     * 暂停调度任务
     * @param triggerkey
     * @return
     * @throws SchedulerException
     */
    public static void unscheduleJob(QuartzScheduleJob job) 
    		throws SchedulerException{ 
    	if (!isShutdown()) {
    		scheduler.pauseJob(new JobKey(job.getJobName(), 
    				job.getJobGroup()));
    		scheduler.pauseTrigger(new TriggerKey(job.getJobName(), 
    				job.getJobGroup())); 
    	}
    }
    
    /**
     * 重启任务调度
     * @param job
     */
    public static void resumeJob(QuartzScheduleJob job){
    	try {
    		if (!isShutdown()) {
    			scheduler.resumeJob(new JobKey(job.getJobName(), 
    					job.getJobGroup()));
    			scheduler.resumeTrigger(new TriggerKey(job.getJobName(), 
    					job.getJobGroup()));
    		}
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
    }
    
    /**
     * 暂停触发器
     * @param job
     */
    public static void pauseTrigger(QuartzScheduleJob job) {  
        try {  
        	if (!isShutdown()) {
        		scheduler.pauseTrigger(new TriggerKey(job.getJobName(), 
        				job.getJobGroup()));// 停止触发器  
        	}
        } catch (SchedulerException e) {  
            throw new RuntimeException(e);  
        }  
    }
 
    /**
     * 恢复触发器
     * @param job
     */
    public static void resumeTrigger(QuartzScheduleJob job) {  
        try {  
        	if (!isShutdown()) {
        		scheduler.resumeTrigger(new TriggerKey(job.getJobName(), 
        				job.getJobGroup()));// 重启触发器  
        	}
        } catch (SchedulerException e) {  
            throw new RuntimeException(e);  
        }  
    } 
    
    /**
     * 删除触发器 
     * @param job
     * @return
     */
    public static boolean removeTrigdger(QuartzScheduleJob job) {  
        TriggerKey triggerKey = new TriggerKey(job.getJobName(), 
        		job.getJobGroup());  
        try {  
        	if (!isShutdown()) {
        		scheduler.pauseTrigger(triggerKey);// 停止触发器  
        	}
            return scheduler.unscheduleJob(triggerKey);// 移除触发器  
        } catch (SchedulerException e) {  
            throw new RuntimeException(e);  
        }  
    }  
	/**
     * 暂停调度中所有的job
     * 恢复任务时，停止时间段之间的任务会被执行
     */
    public static void pauseAll() {
		try {
			if (!isShutdown()) {
				scheduler.pauseAll();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
    
    /**
     * 恢复调度中所有的job
     * @throws SchedulerException
     */
    public  void resumeAll() throws SchedulerException {  
    	if (!isShutdown()) {
    		scheduler.resumeAll();
		}
    }
    
    /**
     * 删除一个任务
     * @param job
     * @param triggerkey
     * @throws SchedulerException
     */
    public static void removeJob(QuartzScheduleJob job,TriggerKey triggerkey) 
           throws SchedulerException{
    	if (!isShutdown()) {
    		scheduler.pauseTrigger(triggerkey);//停止触发器
    		scheduler.unscheduleJob(triggerkey);//移除触发器
    		scheduler.deleteJob(new JobKey(job.getJobName(), 
    				job.getJobGroup()));//删除任务
    	}
    }

	
	/**
	 * 创建一个调度对象
	 * 
	 * @return
	 * @throws SchedulerException
	 */
	private static Scheduler getScheduler() {
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = null;
		try {
			scheduler = sf.getScheduler();
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		return scheduler;
	}
}
